Skip to content

Conversation

@nemecad
Copy link

@nemecad nemecad commented Sep 4, 2025

This PR addresses some previous feedback, most notably:

  • Set-associative TLB (machine::TLB): Implements a set-associative Translation Lookaside Buffer (TLB) frontend over physical memory, handling virtual to physical translation, flush, and replacement policy.
  • Pluggable Replacement Policies (machine::TLBPolicy): Abstract TLB replacement policy interface & implementations (RAND, LRU, LFU, PLRU) for set-associative tables.
  • SV32 Page-Table Walker (machine::PageTableWalker): Performs multi-level page-table walks (SV32) in memory to resolve a virtual address to a physical one.
  • Sv32Pte Bitfield Helpers (sv32.h): SV32-specific definitions: page-table entry (PTE) bitfields, shifts/masks, and PTE to physical address helpers.
  • VirtualAddress (virtual_address.h): Lightweight VirtualAddress wrapper offering raw access, alignment checks, arithmetic, and comparisons.
  • Add supervisor CSRs and sstatus handling: supervisor CSRs (sstatus, stvec, sscratch, sepc, scause, stval, satp) and a write handler that presents sstatus as a masked view of mstatus so supervisor-visible bits stay in sync.
  • Store current privilege level in CoreState: tracking of the hart's current privilege level in CoreState so exception/return handling and visualization can read/update it from the central CoreState structure.

Tests:

  • Add SV32 page-table + TLB integration tests: a set of small assembly tests that exercise the SV32 page-table walker, SATP enablement and the new TLB code. The tests create a root page table and map a virtual page at 0xC4000000, then exercise several scenarios. The tests verify page-table walker behaviour, SATP switching and TLB caching/flush logic. Tests were written based on the consultation.

UI Components:

  • Show current privilege level in core state view:
Snímek obrazovky 2025-09-04 115127
  • Virtual memory configuration to NewDialog:
Snímek obrazovky 2025-09-04 115904
  • TLB visualization and statistics dock:
Snímek obrazovky 2025-09-04 115521
  • VM toggle and "As CPU" memory access view:
Snímek obrazovky 2025-09-04 120034

@jdupak jdupak self-requested a review September 28, 2025 17:17
@jdupak
Copy link
Collaborator

jdupak commented Sep 28, 2025

I am getting this weird zoom.
image

@jdupak
Copy link
Collaborator

jdupak commented Sep 28, 2025

Notice that address sanitizer is failing in CI.

void tlb_update(unsigned way, unsigned set, bool valid, unsigned asid, quint64 vpn, quint64 phys, bool write);

private:
const machine::TLB *tlb;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Who owns this pointer?

#include <cstdint>

namespace machine {
enum TLBType { PROGRAM, DATA };
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does LTB need to know this?

@ppisa
Copy link
Member

ppisa commented Sep 29, 2025

@jdupak thanks for review of interfacing to the memory model architecture.

@ppisa
Copy link
Member

ppisa commented Sep 29, 2025

From my side, the changes to the processor pipeline diagram has been applied directly to the SVG files (src/gui/windows/coreview/schemas), but current design uses DRAW.IO source (extras/core_graphics) as the authoritative source of the pipeline visualization and SVGs are generated from this file. So the commit with SVG change should include extras/core_graphics/diagram.drawio change as well or extras/core_graphics/diagram.drawio change should be commit before SVG files regeneration commit. In long term, I would lean to single SVG file with tags for conditional rendering, but we have not got to that state yet and current solution implemented by @jdupak is based on DRAW.IO and exports controlled by tagging (some documentation there docs/developer/coreview-graphics/using-drawio-diagram.md).

@ppisa
Copy link
Member

ppisa commented Sep 29, 2025

For memory view, I would not complicate it with Show virtual checkbox. I would use only switching between As CPU (VMA), Cached and Raw.

@nemecad nemecad force-pushed the feature/sv32-vm-tlb-ptw-cleanup branch 5 times, most recently from 0bb04d1 to ca4300b Compare October 5, 2025 19:16
@nemecad
Copy link
Author

nemecad commented Oct 5, 2025

@ppisa @jdupak Thank you for your detailed feedback. I appreciate it and have made some changes based on your review. I would be grateful for any further feedback.

jdupak and others added 4 commits October 19, 2025 16:29
This resolves the incorrect zoom behavior.
Add tracking of the hart's current privilege level to the core state so code
handling exceptions/returns and visualization can read/update it from the
central CoreState structure.
Add supervisor CSRs (sstatus, stvec, sscratch, sepc, scause, stval, satp)
and a write handler that presents sstatus as a masked view of mstatus so
supervisor-visible bits stay in sync.
@jdupak jdupak force-pushed the feature/sv32-vm-tlb-ptw-cleanup branch from ca4300b to a6cbf71 Compare October 19, 2025 14:48
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a typo in the dir name

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no cmake logic to run these tests. I think we want to run them as cli tests.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the comment. I’ve added the CMake logic to run these as CLI tests in the commit 7a204cf.

jdupak and others added 5 commits October 19, 2025 18:11
Add privilege level mapping to the GUI so the current hart privilege
(UNPRIV, SUPERV, HYPERV, MACHINE) is displayed in core state visualization.
Extend NewDialog with controls for virtual memory setup, including TLB
number of sets, associativity, and replacement policy.
Introduce new components for displaying and
tracking TLB state similar to cache. TLBViewBlock and TLBAddressBlock render per-set
and per-way TLB contents, updated on tlb_update signals. TLBViewScene
assembles these views based on associativity. TLBDock integrates into
the GUI, showing hit/miss counts, memory accesses, stall cycles, hit rate,
and speed improvement, with live updates from the TLB.
Introduce an "As CPU (VMA)" access option in the cached access selector to
render memory contents as observed by the CPU through the
frontend interface.
@jdupak jdupak force-pushed the feature/sv32-vm-tlb-ptw-cleanup branch from a6cbf71 to bc32933 Compare October 19, 2025 16:13
@jdupak
Copy link
Collaborator

jdupak commented Oct 19, 2025

I pushed some slight edits. Barring the issue with new tests not being run I am fine with merging this.

@ppisa
Copy link
Member

ppisa commented Oct 29, 2025

I am going through the code. I have one overall remark, that there are lot of formatting changes included in functional changes. I am not reluctant to formatting changes even that I think that sometimes formatting left by human to align for example some case lines into columns etc. has some value. But formatting changes unrelated to the functional changes make review harder. So I would keep with patches as they are but I would suggest to separate formatting, even over all later modified files in series, separate from functional changes.

@ppisa
Copy link
Member

ppisa commented Oct 29, 2025

I am do not like is_mmio_region() and bypass_mmio() concept. The peripherals accesses should go through regular address translation. It is responsibility of the OS to map regions related to I/O into virtual address space of kernel and or even user application, i.e. for mmap() like accesses.

As for enabling cache for accesses there is a hack in the QtRvSim which enforces next uncached region

Cache::Cache
    uncached_start(0xf0000000_addr)
    uncached_last(0xfffffffe_addr)

In the longer term, cacheability should be controlled from page tables. But PBMT (Page-Based Memory Types) are supported only for Sv39 and bigger translation configurations, see Chapter 14. "Svpbmt" Extension for Page-Based Memory Types

Mode Value Requested Memory Attributes
PMA 0 None
NC 1 Non-cacheable, idempotent, weakly-ordered (RVWMO), main memory
IO 2 Non-cacheable, non-idempotent, strongly-ordered (I/O ordering), I/O
- 3 Reserved for future standard use

But the physical region marked to skip caching in cache implementation (current state) should be enough for now.

@ppisa
Copy link
Member

ppisa commented Oct 29, 2025

Not so critical for now, but should be solved in the longer time perspective. SRET can be executed even in M mode. So the type of the return should be propagated to the control_state->exception_return in the Core::memory(const ExecuteInterstage &dt). It is question if to add signal which goes through all stages (more readable) or to use bit from instruction for local decode of the type. MRET should not be allowed in system mode. In general, I think that current version does not mark system level instructions and access to the system and machine mode CSRs as invalid in U mode. So some masking would be required on the decode level in future. Some more flags needs to be added into enum InstructionFlags to allow that checking and flags_to_check and it should then be updated on mode transition.

The behavior of xRET instructions is described in 3.1.6.1. Privilege and Global Interrupt-Enable Stack in mstatus register. When SRET is executed in M mode then it executes the same as in the S mode but it
should clear MPRV=0. This is to allow emulate some system level operations in machine level code.

@ppisa
Copy link
Member

ppisa commented Oct 29, 2025

It seems that TLBs are updated from the start of the system. The TLB and its updates should be enable only when root register is set. And they should not be updated in M mode at all.

@jdupak
Copy link
Collaborator

jdupak commented Oct 29, 2025

There is one actual issue from CI: you cannot use ftruncate. It fails compilation on Win.

@jdupak
Copy link
Collaborator

jdupak commented Oct 30, 2025

There is one actual issue from CI: you cannot use ftruncate. It fails compilation on Win.

Never mind, this is broken on master. I will fix that. It does not block this PR.

Add a set of small assembly tests that exercise the SV32 page-table walker,
SATP enablement and the new TLB code. The tests create a root page
table and map a virtual page at 0xC4000000, then exercise several scenarios.
The tests verify page-table walker behaviour, SATP switching and TLB caching/flush logic.
Tests were written based on the consultation.
@nemecad nemecad force-pushed the feature/sv32-vm-tlb-ptw-cleanup branch from 7a204cf to b8728d1 Compare November 2, 2025 14:11
Restructure the virtual memory test directory to align with the rest of the tests, and add CMake logic for running them.
@nemecad nemecad force-pushed the feature/sv32-vm-tlb-ptw-cleanup branch from b8728d1 to 0ae766f Compare November 2, 2025 14:15
Ensure that TLBs are only updated when the root register is set, and disable TLB updates while running in Machine mode.
@nemecad nemecad force-pushed the feature/sv32-vm-tlb-ptw-cleanup branch from c846a9e to 442a091 Compare November 2, 2025 16:54
Decode MRET/SRET/URET in the decode stage, carry the return type through interstage registers, and pass it to ControlState::exception_return in the memory stage. Mark returns illegal if they request a higher privilege (e.g., MRET in S-mode). When returning from M to a less-privileged mode, clear MPRV per the privileged spec.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants